﻿using System;

namespace jQueryLib
{
    public abstract class Deferred : Promise
    {
        /// <summary>
        /// Return a Deferred's Promise object.
        /// </summary>
        /// <returns></returns>
        public abstract Promise Promise();

        //Extend: It is like add promise aspect to target, how to translate here?
        //public abstract Promise Promise(object target);

        /// <summary>
        /// Call the progressCallbacks on a Deferred object.
        /// </summary>
        public abstract void Notify();

        /// <summary>
        /// Call the progressCallbacks on a Deferred object with the given args.
        /// </summary>
        /// <param name="arg"></param>
        public abstract void Notify(object arg);

        /// <summary>
        /// Call the progressCallbacks on a Deferred object.
        /// </summary>
        /// <param name="context">Context passed to the progressCallbacks as the this object.</param>
        public abstract void NotifyWith(object context);

        /// <summary>
        /// Call the progressCallbacks on a Deferred object with the given context and args.
        /// </summary>
        /// <param name="context">Context passed to the progressCallbacks as the this object.</param>
        /// <param name="arg"></param>
        public abstract void NotifyWith(object context, object arg);

        /// <summary>
        /// Reject a Deferred object and call any failCallbacks.
        /// </summary>
        public abstract void Reject();

        /// <summary>
        /// Reject a Deferred object and call any failCallbacks with the given args.
        /// </summary>
        /// <param name="arg"></param>
        public abstract void Reject(object arg);

        /// <summary>
        ///  Reject a Deferred object and call any failCallbacks with the given context.
        /// </summary>
        /// <param name="context">Context passed to the failCallbacks as the this object.</param>
        public abstract void RejectWith(object context);

        /// <summary>
        ///  Reject a Deferred object and call any failCallbacks with the given context and args.
        /// </summary>
        /// <param name="context">Context passed to the failCallbacks as the this object.</param>
        /// <param name="arg"></param>
        public abstract void RejectWith(object context, object arg);

        /// <summary>
        /// Resolve a Deferred object and call any doneCallbacks.
        /// </summary>
        public abstract void Resolve();

        /// <summary>
        /// Resolve a Deferred object and call any doneCallbacks with the given args.
        /// </summary>
        /// <param name="arg"></param>
        public abstract void Resolve(object arg);

        /// <summary>
        /// Resolve a Deferred object and call any doneCallbacks with the given context.
        /// </summary>
        /// <param name="context">Context passed to the doneCallbacks as the this object.</param>
        public abstract void ResolveWith(object context);

        /// <summary>
        /// Resolve a Deferred object and call any doneCallbacks with the given context and args.
        /// </summary>
        /// <param name="context">Context passed to the doneCallbacks as the this object.</param>
        /// <param name="arg"></param>
        public abstract void Resolve(object context, object arg);


        public abstract Promise Always(Delegate del);

        public abstract Promise Always(params Delegate[] dels);

        public abstract Promise Done(Delegate del);

        public abstract Promise Done(params Delegate[] dels);

        public abstract Promise Fail(Delegate del);

        public abstract Promise Fail(params Delegate[] del);

        public abstract string State();

        public abstract Promise Then(Delegate done, Delegate fail);

        public abstract Promise Then(Delegate[] done, Delegate[] fail);

        public abstract Promise Then(Delegate done, Delegate fail, Delegate progress);

        public abstract Promise Then(Delegate[] done, Delegate[] fail, Delegate[] progress);

        public abstract Promise Progress(Delegate del);

        public abstract Promise Progress(Delegate[] del);
    }
}
